package com.example.a02;

import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletPath;
import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletRegistrationBean;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext;
import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class A02Application {

  public static void main(String[] args) {
//    testClassPathXmlApplicationContext();
//    testAnnotationConfigApplicationContext();
    testAnnotationConfigServletWebServerApplicationContext();


    DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
    System.out.println("读取之前");
    for (String name : beanFactory.getBeanDefinitionNames()) {
      System.out.println(name);
    }
    System.out.println("读取之后");
    XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);
    reader.loadBeanDefinitions(new ClassPathResource("a02.xml"));
    for (String name : beanFactory.getBeanDefinitionNames()) {
      System.out.println(name);
    }
  }


  private static void testClassPathXmlApplicationContext() {

    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("a02.xml");
    for (String beanDefinitionName : context.getBeanDefinitionNames()) {
      System.out.println(beanDefinitionName);
    }
  }

  private static void testAnnotationConfigApplicationContext() {
    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
    for (String name : context.getBeanDefinitionNames()) {
      System.out.println(name);
    }
  }

  private static void testAnnotationConfigServletWebServerApplicationContext() {
    AnnotationConfigServletWebServerApplicationContext context = new AnnotationConfigServletWebServerApplicationContext(WebConfig.class);
  }

  @Configuration
  static class Config{
    @Bean
    public Bean1 bean1(){
      return new Bean1();
    }
    @Bean
    public Bean2 bean2(Bean1 bean1){
      Bean2 bean2 = new Bean2();
      bean2.setBean1(bean1);
      return bean2;
    }
  }

  @Configuration
  static class WebConfig{
    @Bean
    public ServletWebServerFactory servletWebServerFactory(){
      return new TomcatServletWebServerFactory();
    }
    @Bean
    public DispatcherServlet dispatcherServlet(){
      return new DispatcherServlet();
    }
    @Bean
    public DispatcherServletRegistrationBean dispatcherServletRegistrationBean(DispatcherServlet dispatcherServlet){
      return new DispatcherServletRegistrationBean(dispatcherServlet,"/");
    }
    @Bean("/hello")
    public Controller controller1(){
      return (request, response) -> {
        response.getWriter().write("helloword");
        return null;
      };
    }
  }

  static class Bean1 {}

  static class Bean2 {
    private Bean1 bean1;

    public Bean1 getBean1() {
      return bean1;
    }

    public void setBean1(Bean1 bean1) {
      this.bean1 = bean1;
    }
  }
}
